<script lang="ts" setup>
import { ref } from 'vue';
import { useSSE } from '@sa/alova/client';
import { alovaEs } from '@/service/request';
import { renderMarkdown } from '@/utils/markdown';

// 聊天相关状态
const messages = ref<Array<{ role: string; content: string; reasoningContent: string }>>([
  { role: 'assistant', content: '你好！我是AI助手，有什么可以帮您的吗？', reasoningContent: '' }
]);

const userInput = ref('');
const isLoading = ref(false);

const method = (value: string) => alovaEs.Get('/chat/id1', { params: { prompt: value } });

const { readyState, onMessage, onError, close, send, on } = useSSE(method);
onMessage(({ data }) => {
  if (readyState.value !== 1) {
    return;
  }

  try {
    const msg = JSON.parse(data);
    const lastMessage = messages.value[messages.value.length - 1];

    // 确保只处理当前会话的消息
    if (lastMessage.role === 'assistant') {
      if (msg.isThinking) {
        lastMessage.reasoningContent += msg.content;
      } else {
        lastMessage.content += msg.content;
      }

      scrollToBottom();
    }
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error('消息解析失败:', e);
  }
});

onError(_event => {
  // eslint-disable-next-line no-console
  console.error('error');
  close();
});

on('completed', _event => {
  close();
});

// 发送消息
async function sendMessage() {
  if (!userInput.value.trim() || isLoading.value) return;

  isLoading.value = true; // 添加加载状态锁定
  const userMessage = userInput.value;
  messages.value.push({ role: 'user', content: userMessage, reasoningContent: '' });
  messages.value.push({ role: 'assistant', content: '', reasoningContent: '' });
  userInput.value = '';
  try {
    await send(userMessage); // 确保使用 await
  } catch (error) {
    // eslint-disable-next-line no-console
    console.error('发送失败:', error);
    messages.value.pop(); // 移除空的助手消息
  } finally {
    isLoading.value = false;
  }
}

function scrollToBottom() {
  const container = document.querySelector('.messages-container');
  container?.scrollTo({
    top: container.scrollHeight,
    behavior: 'smooth'
  });
}
</script>

<template>
  <div class="h-screen flex">
    <NSplit :min="0.2" :max="0.2" default-size="240px">
      <template #1>
        <NCard title="聊天" :bordered="false" class="h-full">
          <NList>
            <NListItem
              v-for="(item, index) in [{ title: '新对话' }, ...Array(1).fill({ title: '历史对话' })]"
              :key="index"
            >
              <NThing :title="item.title" />
            </NListItem>
          </NList>
        </NCard>
      </template>
      <template #2>
        <div class="chat-layout">
          <div class="messages-container">
            <div v-for="(message, index) in messages" :key="index" class="message" :class="message.role">
              <div class="message-wrapper">
                <NAvatar round :size="48" class="message-avatar" />
                <NCard :bordered="false" :class="`message-card ${message.role}`">
                  <div class="message-content">
                    <div v-if="isLoading && index === messages.length - 1 && !message.content">
                      <div class="dot-flashing"></div>
                    </div>
                    <div v-else class="markdown-body">
                      <div v-html="renderMarkdown(message.reasoningContent)"></div>
                      <div v-html="renderMarkdown(message.content)"></div>
                    </div>
                  </div>
                </NCard>
              </div>
            </div>
          </div>

          <div class="input-area">
            <NInput
              v-model:value="userInput"
              type="textarea"
              placeholder="输入您的问题..."
              :autosize="{ minRows: 2, maxRows: 5 }"
              @keydown.enter.prevent="sendMessage"
            />
            <NSpace justify="end">
              <NButton type="primary" class="mt-2" :disabled="!userInput.trim() || isLoading" @click="sendMessage">
                {{ isLoading ? '发送中...' : '发送' }}
              </NButton>
            </NSpace>
          </div>
        </div>
      </template>
    </NSplit>
  </div>
</template>

<style scoped>
.chat-layout {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 180px);
  overflow: hidden;
  width: 100%;
}

.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: calc(100vh - 306px);
  box-sizing: border-box;
  width: 100%;
  background: #fff;
}

.message {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}

.input-area {
  height: 126px;
  padding: 16px;
  background-color: #fff;
  border-top: 1px solid #f0f0f0;
  position: relative;
  z-index: 1;
  box-sizing: border-box;
}

.message-wrapper {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  width: 100%;
}

.message-avatar {
  flex-shrink: 0;
}

.message-card {
  width: calc(100% - 120px);
  max-width: calc(100% - 120px);
  min-width: 120px;
  word-break: break-word;
  position: relative;
  padding: 12px 16px;
  background-color: #d7e6f5;
}

.message.user {
  align-self: flex-end;
}

.message.user .message-wrapper {
  flex-direction: row-reverse;
}

.message.user .message-card {
  width: calc(100% - 120px);
  max-width: calc(100% - 120pxpx);
  background-color: #d7e6f5;
  border-radius: 12px 12px 12px 12px;
}

.message.assistant {
  align-self: flex-start;
}

.message.assistant .message-card {
  background-color: #d7e6f5;
  border-radius: 12px 12px 12px 12px;
}

.message-content {
  width: 100%;
  max-width: 100%;
  white-space: pre-wrap;
  word-break: normal;
  overflow-wrap: break-word;
  min-height: 20px;
  line-height: 1.6;
}

.dot-flashing {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 4px;
  background-color: #888;
  color: #888;
  animation: dotFlashing 1s infinite linear;
  animation-delay: 0s;
}

.dot-flashing::before,
.dot-flashing::after {
  content: '';
  display: inline-block;
  position: absolute;
  top: 0;
  width: 8px;
  height: 8px;
  border-radius: 4px;
  background-color: #888;
  color: #888;
}

.dot-flashing::before {
  left: -12px;
  animation: dotFlashing 1s infinite linear;
  animation-delay: -0.2s;
}

.dot-flashing::after {
  left: 12px;
  animation: dotFlashing 1s infinite linear;
  animation-delay: 0.2s;
}

@keyframes dotFlashing {
  0% {
    background-color: #888;
  }
  50%,
  100% {
    background-color: rgba(136, 136, 136, 0.2);
  }
}

/* Markdown 内容样式 */
.markdown-body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  line-height: 1.1;
}

.markdown-body :deep(pre) {
  background: #f6f8fa;
  padding: 6px;
  border-radius: 6px;
  margin: 6px 0;
}

.markdown-body :deep(code) {
  padding: 0.1em 0.2em;
  background-color: rgba(175, 184, 193, 0.2);
  border-radius: 6px;
  font-family:
    ui-monospace,
    SFMono-Regular,
    SF Mono,
    Menlo,
    Consolas,
    Liberation Mono,
    monospace;
}

.markdown-body :deep(blockquote) {
  border-left: 4px solid #dfe2e5;
  color: #6a737d;
  margin: 0;
  padding: 0 1em;
}

.markdown-body :deep(table) {
  border-collapse: collapse;
  margin: 1em 0;
}

.markdown-body :deep(th),
.markdown-body :deep(td) {
  border: 1px solid #dfe2e5;
  padding: 6px 12px;
}

.markdown-body :deep(img) {
  max-width: 100%;
}

.markdown-body :deep(think) {
  display: block;
  border-left: 2px solid #3498db;
  padding: 6px 12px;
  margin: 12px 0;
  background-color: #f8f9fa;
  color: #a0a0a0;
}
</style>
